﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UTJ;

public class Knife : MonoBehaviour
{
    // Whether to use collision as texture update condition.
    public bool useCollision;
    // Whether to use mouse down as texture update condition.
    public bool useMouseInput;

    public Vector3 Target
    {
        set
        {
            target = value;
        }
        get
        {
            return target;
        }
    }
    Vector3 target;

    Rigidbody rigid;

    const int texture_pixel_count = 1024 * 1024;
    public int painter_size = 10;
    Color[] colors;
    bool dirty = true;
    public Texture2D length_texture;
    public HairInstance hairInstance;
    // Start is called before the first frame update

    void Start()
    {
        colors = new Color[texture_pixel_count];
        for (int i = 0; i < texture_pixel_count; ++i)
        {
            colors[i] = Color.black;
        }

        rigid = GetComponent<Rigidbody>();
        // hairInstance = GameObject.Find("Hair").GetComponent<HairInstance>();
    }

    // Update is called once per frame
    void Update()
    {
        TryUpdateWithMouse();
        if (dirty)
        {
            length_texture.Apply();
            // hairInstance.AssignTexture(hwi.TextureType.LENGTH, length_texture);
            hairInstance.AssignTexture(hwi.TextureType.DENSITY, length_texture);
            // hairInstance.AssignTexture(hwi.TextureType.ROOT_COLOR, length_texture);
            dirty = false;
        }
    }

    private void FixedUpdate()
    {
        if (target == null) return;
        Vector3 currLoc = transform.position;
        Vector3 dist = target - currLoc;
        Vector3 currVel = rigid.velocity;
        rigid.AddForce(dist * 0.1f - currVel * 0.1f, ForceMode.VelocityChange);
    }

    void TryUpdateWithMouse()
    {
        if (!useMouseInput) return;
        if (!Input.GetMouseButton(0))
            return;
        Camera cam = Camera.main;
        RaycastHit hit;
        if (!Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out hit))
        {
            Debug.Log("no mouse hit.");
            return;
        }
        UpdateWithRaycastHit(hit);
    }

    void UpdateWithRaycastHit(RaycastHit hit)
    {
        if (hit.collider.name != "refined_bear") return;
        Renderer renderer = hit.collider.GetComponent<Renderer>();
        MeshCollider meshCollider = hit.collider as MeshCollider;
        if (renderer == null || renderer.material == null || renderer.material.mainTexture == null || meshCollider == null)
        {
            return;
        }
        dirty = true;
        // Texture2D tex = (Texture2D)renderer.material.mainTexture;
        Vector2 pixelUV = hit.textureCoord;
        // Debug.Log(pixelUV.x.ToString("n2") + " " + pixelUV.y.ToString("n2"));
        
        int x = (int)(length_texture.width * pixelUV.x);
        int y = (int)(length_texture.height * (1-pixelUV.y));
        int width = Mathf.Min(length_texture.width - x, painter_size);
        int height = Mathf.Min(length_texture.height - y, painter_size);
        // for debugging:
        // x = 0; y = 0;
        // width = length_texture.width;
        // height = length_texture.height;
        length_texture.SetPixels(x, y, width, height, colors);
    }

    private void OnCollisionStay(Collision collision)
    {
        if (!useCollision) return;
        Debug.Log(collision.contacts.Length);
        foreach (ContactPoint contact in collision.contacts)
        {
            if (contact.otherCollider.name == "refined_bear")
            {
                Debug.DrawRay(contact.point, contact.normal, Color.red);
                RaycastHit hit;
                if (!Physics.Raycast(contact.point - contact.normal, contact.normal, out hit))
                {
                    return;
                }
                UpdateWithRaycastHit(hit);
                // hairInstance.AssignAllTextures();
            }
        }

    }
}
